package ui;

/**
 * @author peedarpk
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JPanel;

import lights.LightRunnable;
import obj.Edge;
import obj.Junction;
import obj.Node;
import obj.Path;
import sim.VehicleComponent;
import sim.VehicleFactory;

public class Simulator extends JPanel {

	private static final long serialVersionUID = 3271124102273173061L;
	public List<Path> pathsList = new ArrayList<Path>();
	private static final int TILE_SIZE = 10;
	private List<Junction> junctionList = new ArrayList<Junction>();
	private VehicleComponent comp;

	public Node[][] nodesMatrix;
	public Map<Edge, Set<String>> carsInEdgesMap = new HashMap<Edge, Set<String>>();

	public Simulator() {
		setBackground(new Color(107, 142, 35));
		setLayout(new BorderLayout(0, 0));
		comp = new VehicleComponent();
		comp.setBackground(new Color(0, 128, 0));
		comp.addJunctions(junctionList);
		add(comp);
	}

	public void setData(List<Edge> elist, List<Node> nList, List<Path> pList, List<Junction> jList, Node[][] matrix) {
		this.pathsList = pList;
		this.junctionList = jList;
		this.nodesMatrix = matrix;
	}

	/**
	 * Method to start the simulation
	 */
	public void startSimulation() {
		for (Path path : this.pathsList) {
			/* invoke the Vehicle Factory in each path to generate vehicles */
			Runnable runnable = new VehicleFactory(comp, path, nodesMatrix, carsInEdgesMap);
			Thread thread = new Thread(runnable);
			thread.start();
			MainUI.registerSubscriber((VehicleFactory) runnable);
		}

		/* start lights thread */
		if (!junctionList.isEmpty()) {
			Runnable runnable = new LightRunnable(junctionList, comp, carsInEdgesMap);
			Thread thread = new Thread(runnable);
			thread.start();
			System.out.println("lights started.......");
		}

	}

	private List<Path2D> getShapesList(ArrayList<Path> pathsList) {
		Path2D pathShape;
		List<Path2D> shapesList = new ArrayList<Path2D>();
		for (Path p : pathsList) {
			pathShape = new Path2D.Float();
			List<Edge> edges = p.getEdgesList();
			int count = 0;
			int[] xpoints = new int[edges.size() * 2];
			int[] ypoints = new int[edges.size() * 2];
			int xValue;
			int yValue;

			for (Edge e : edges) {
				Node sNode = e.getStartNode();
				xValue = sNode.getxBox() * TILE_SIZE;
				yValue = sNode.getyBox() * TILE_SIZE;
				xpoints[count] = xValue;
				ypoints[count] = yValue;
				count++;
				Node eNode = e.getEndNode();
				xValue = eNode.getxBox() * TILE_SIZE;
				yValue = eNode.getyBox() * TILE_SIZE;
				xpoints[count] = xValue;
				ypoints[count] = yValue;
				count++;
			}

			for (int i = 0; i < xpoints.length; i++) {
				if (i == 0) {
					pathShape.moveTo(xpoints[i], ypoints[i]);
				} else {
					pathShape.lineTo(xpoints[i], ypoints[i]);
				}
			}

			shapesList.add(pathShape);

		}

		return shapesList;
	}
}
